package generator

import (
	"fmt"
	"path/filepath"

	conf "github.com/tal-tech/go-zero/tools/goctl/config"
	"github.com/tal-tech/go-zero/tools/goctl/rpc/parser"
	"github.com/tal-tech/go-zero/tools/goctl/util"
	"github.com/tal-tech/go-zero/tools/goctl/util/format"
)

const svcTemplate = `package svc

import (
	{{.imports}}
	"github.com/tal-tech/go-zero/core/stores/cache"
	"github.com/tal-tech/go-zero/core/syncx"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"gorm.io/gorm/schema"
)

type ServiceContext struct {
	Config config.Config
	DB  *gorm.DB
	Cache  cache.Cache
}

func NewServiceContext(c config.Config) *ServiceContext {
	conn, _ := gorm.Open(mysql.New(mysql.Config{
		DSN:               c.Database.DSN,
		DefaultStringSize: 171,//数据库varchar类型的默认值
	}), &gorm.Config{
		NamingStrategy: schema.NamingStrategy{
			TablePrefix:   "",   //表前缀
			SingularTable: true, //使用单数表名
		},
		SkipDefaultTransaction: false, //启用事务
		DryRun:                                   false, //禁止SQL空跑
		DisableForeignKeyConstraintWhenMigrating: true,  //创建逻辑外键
		Logger:logger.Default.LogMode(logger.Info),	 //输出 SQL语句
	})
	return &ServiceContext{
		Config: c, 
		DB: conn,
		Cache: cache.New(c.CacheRedis, syncx.NewSingleFlight(), cache.NewStat(""), nil),
	}
}

func (it *ServiceContext)AutoMigrate(){
	it.DB.AutoMigrate()
}
`

// GenSvc generates the servicecontext.go file, which is the resource dependency of a service,
// such as rpc dependency, model dependency, etc.
func (g *DefaultGenerator) GenSvc(ctx DirContext, _ parser.Proto, cfg *conf.Config) error {
	dir := ctx.GetSvc()
	svcFilename, err := format.FileNamingFormat(cfg.NamingFormat, "service_context")
	if err != nil {
		return err
	}

	fileName := filepath.Join(dir.Filename, svcFilename+".go")
	text, err := util.LoadTemplate(category, svcTemplateFile, svcTemplate)
	if err != nil {
		return err
	}

	return util.With("svc").GoFmt(true).Parse(text).SaveTo(map[string]interface{}{
		"imports": fmt.Sprintf(`"%v"`, ctx.GetConfig().Package),
	}, fileName, false)
}
